package com.example.demo.niuke.huawei_b;

import java.util.Scanner;

/**
 * ******************************************************
 *
 * @author liugh9
 * @version 1.0
 * @classname _9识别有效的IP地址和掩码并进行分类统计
 * @description
 * @date 2023/09/02 8:22
 * <p>
 * ******************************************************
 */
public class _9识别有效的IP地址和掩码并进行分类统计 {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int[] result = {0, 0, 0, 0, 0, 0, 0};

        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String ipAndMask = in.nextLine();

            if (ifIgnore(ipAndMask)) {
                continue;
            }
            if (ifIllegal(ipAndMask)) {
                result[5]++;
                continue;
            }
            if (ifPrivate(ipAndMask)) {
                result[6]++;
            }
            char tempChar = ifABCDE(ipAndMask);
            switch (tempChar) {
                case 'A':
                    result[0]++;
                    break;
                case 'B':
                    result[1]++;
                    break;
                case 'C':
                    result[2]++;
                    break;
                case 'D':
                    result[3]++;
                    break;
                case 'E':
                    result[4]++;
                    break;
                default:
                    break;
            }
        }
        // 输出语句
        for (int i = 0; i < 6; i++) {
            System.out.print(result[i] + " ");
        }
        System.out.print(result[6] + "\n");
        in.close();
    }

    /*
     * 返回n个长度的字符串数组存储ip位和掩码位(一般为8)
     * 129.125.4.~255.255.255.255 这种时候长度为7
     * 129.125.4.~255.255.255. 这种时候长度为6
     */
    public static String[] toStringArr(String ipAndMask) {
        String[] tempIp = ipAndMask.split("~")[0].split("\\."); // ip位
        String[] tempMask = ipAndMask.split("~")[1].split("\\."); // 掩码位
        int n = tempIp.length + tempMask.length;
        String[] result = new String[n];

        // index0~3存ip,4~7存mask
        for (int i = 0; i < tempIp.length; i++) {
            result[i] = tempIp[i];
        }
        for (int i = tempIp.length; i < n; i++) {
            result[i] = tempMask[i - tempIp.length];
        }
        return result;
    }

    /*
     * 将掩码转换为32位的二进制字符串
     * 例如255.255.128.0 --> 11111111 11111111 10000000 00000000
     */
    public static String toBinary(String ipAndMask) {
        String[] input = toStringArr(ipAndMask);// 4~7存储掩码
        String result = new String();

        for (int i = 4; i < input.length; i++) {
            Integer maskNum = Integer.valueOf(input[i]);
            String tempStr = Integer.toBinaryString(maskNum);
            // 补齐8位
            while (tempStr.length() < 8) {
                tempStr = "0" + tempStr;
            }
            result += tempStr;
        }
        return result;
    }

    // 需要忽略返回true,否则返回false
    public static boolean ifIgnore(String ipAndMask) {
        String[] input = toStringArr(ipAndMask);
        switch (input[0]) {
            case "0":
            case "127":
                return true;
            default:
                return false;
        }
    }

    // ip错误返回true，否则返回false。默认ip不被忽略
    public static boolean ifIllegal(String ipAndMask) {
        String[] input = toStringArr(ipAndMask);
        String mask = toBinary(ipAndMask);

        // 先遍历，如果input中存在""或者<0或者>255或者input.length != 8,说明ip错误，return true;
        for (String str : input) {
            if (input.length != 8 || str.equals("") || Integer.valueOf(str) < 0 ||
                    Integer.valueOf(str) > 255) {
                //System.out.println("a");
                return true;
            }
        }

        /*
         * 1111111111...00000 中包含11、10、00 --> 合法
         * 1111111111...11111 中包含11 --> 非法
         * 0000000000...00000 中包含00 --> 非法
         * 1111110010...11010 中包含11、10、00、01 --> 非法
         * 所以当mask包含10并且不包含01时说明掩码合法
         */
        if (mask.contains("10") && !mask.contains("01")) {
            //System.out.println("b");
            return false;
        }
        return true;
    }

    // 返回'A'|'B'|'C'|'D'|'E'表示ip所处类。默认ip合法
    public static char ifABCDE(String ipAndMask) {
        String[] input = toStringArr(ipAndMask);

        Integer tempi = Integer.valueOf(input[0]);
        if (tempi > 0 && tempi < 127) {
            return 'A';
        } else if (tempi > 127 && tempi < 192) {
            return 'B';
        } else if (tempi > 191 && tempi < 224) {
            return 'C';
        } else if (tempi > 223 && tempi < 240) {
            return 'D';
        } else {
            return 'E';
        }
    }

    // 私网ip返回true，否则返回false。默认ip合法
    public static boolean ifPrivate(String ipAndMask) {
        String[] input = toStringArr(ipAndMask);

        Integer tempi = Integer.valueOf(input[0]);
        Integer tempi2 = Integer.valueOf(input[1]);

        // 10.0.0.0 ~ 10.255.255.255
        if (tempi == 10) {
            //System.out.println("c");
            return true;
        }

        // 172.16.0.0 ~ 172.31.255.255
        if (tempi == 172 && tempi2 > 15 && tempi2 < 32) {
            //System.out.println("c");
            return true;
        }
        // 192.168.0.0 ~ 192.168.255.255
        if (tempi == 192 && tempi2 == 168) {
            //System.out.println("c");
            return true;
        }

        return false;
    }
}